﻿using System;
using System.ComponentModel.Composition;
using Microsoft.Practices.ServiceLocation;
using Mockery.Core.CommonContainer;
using StructureMap;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;
using StructureMap.ServiceLocatorAdapter;

namespace CommonContainer.Mockery.StructureMap
{
    [Export(typeof(ICommonContainerBuilder))]
    public class StructureMapContainerBuilder : Registry, ICommonContainerBuilder
    {
        #region ICommonContainerBuilder Members

        /// <summary>
        /// Instantiates a new, clean StructureMap Container builder instance
        /// </summary>
        /// <returns></returns>
        public ICommonContainerBuilder New()
        {
            return new StructureMapContainerBuilder();
        }

        /// <summary>
        /// Register a singleton instance by a resolve type that differs from the instance
        /// </summary>
        /// <typeparam name="TType">resolve type</typeparam>
        /// <param name="resolveType">resolve type Type instance</param>
        /// <param name="instance">object instance</param>
        public void RegisterInstance<TType>(Type resolveType, TType instance)
        {
            ForRequestedType(resolveType).CacheBy(InstanceScope.Singleton).TheDefaultIs(() => instance);
           
            //ForSingletonOf<TType>().CacheBy(InstanceScope.Singleton).Use(instance);
            //For<TType>().Singleton().Use(instance);
        }

        /// <summary>
        /// Register a singleton instance by a resolve type that differs from the concrete type
        /// </summary>
        /// <typeparam name="TType">concrete type</typeparam>
        /// <typeparam name="TResolveType">resolve type</typeparam>
        public void RegisterType<TType, TResolveType>() where TType : TResolveType
        {
            ForRequestedType<TResolveType>().CacheBy(InstanceScope.Singleton).TheDefaultIsConcreteType<TType>();
            //ForSingletonOf<TResolveType>().CacheBy(InstanceScope.Singleton).Use<TType>();
            //For<TResolveType>().Singleton().Add<TType>();
        }

        /// <summary>
        /// Register a singleton instance whose type is the same as the resolve type
        /// </summary>
        /// <typeparam name="TType">resolve type</typeparam>
        public void RegisterType<TType>()
        {
            ForRequestedType<TType>().CacheBy(InstanceScope.Singleton).TheDefaultIsConcreteType<TType>();
            //For<TType>().Singleton();
        }

        /// <summary>
        /// returns the service locator instance
        /// </summary>
        public IServiceLocator ServiceLocator
        {
            get { return new StructureMapServiceLocator(new Container(this)); }
        }

        #endregion
    }
}
